package com.ncs.nc.controller;

import com.google.gson.Gson;
import com.ncs.nc.entity.CustomerDto;
import com.ncs.nc.entity.EventDto;
import com.ncs.nc.mq.RabbitSender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 测试Rabbit消息简单文本
 */
@RestController
@RequestMapping("rabbit/mq")
public class RabbitController {

    private static final Logger log= LoggerFactory.getLogger(RabbitController.class);

    @Autowired
    private RabbitSender sender;

    //发送简单消息
    @RequestMapping(value="send/simple",method= RequestMethod.GET)
    public String sendSimple(){
        String status="success";
        try{
            sender.sendMsg();
        }catch (Exception e){
            e.printStackTrace();
            status="failed";
        }
        return status;
    }

    /**
     * 基于FanoutExchange的消息模型发送消息
     */
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private Environment env;

    @RequestMapping(value="send/fanout",method=RequestMethod.GET)
    public String sendFanoutMsg(){
        String status="success";
        try{
            log.info("----基于FanoutExchange的消息模型-生产者----");
            //通过实体类对象实例构造消息--设置消息的持久化
            EventDto dto=new EventDto(10,"Order","订单支付消息","这是订单支付成功后的消息");
            Message msg= MessageBuilder.withBody(new Gson().toJson(dto).getBytes())
                    .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
                    .build();
            //设置交换器，并将消息发送进交换器绑定的消息模型中
            rabbitTemplate.setExchange(env.getProperty("mq.fanout.exchange.name"));
            rabbitTemplate.send(msg);
            log.info("基于FanoutExchange的消息模型~生产者成功发送小...");
        }catch(Exception e){
            e.printStackTrace();
            status="failed";
        }
        return status;
    }

    /**
     * 基于DirectExchange消息模型发送消息
     */
    @RequestMapping(value = "send/direct",method=RequestMethod.GET)
    public String sendDirectMsg(){
        String status="success";
        try{
            log.info("--DirectExchange消息模型发送消息 - 生产者 ----");
            //通过实体类对象实例构造消息-设置消息的持久化
            EventDto deto=new EventDto(20,"Log","用户新增成功","用户新增成功后写入日志信息");
            Message msg=MessageBuilder.withBody(new Gson().toJson(deto).getBytes())
                    .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
                    .build();
            //设置交换器，并将消息发送进交换器绑定的消息模型中
            rabbitTemplate.setExchange(env.getProperty("mq.direct.exchange.name"));
            rabbitTemplate.setRoutingKey(env.getProperty("mq.direct.routing.key"));
            rabbitTemplate.send(msg);
            log.info("基于DirectExchange消息模型发送消息 ~ 生产者成功发送消息...");
        }catch(Exception e){
            e.printStackTrace();
            status="failed";
        }
        return status;
    }

    //基于TopicExchange的消息模型发送消息 - 来源途径为官网
    @RequestMapping(value = "send/topic/v1",method=RequestMethod.GET)
    public String sentTopicV1(){
        String status="success";
        try{
            log.info("\n\n --基于TopicExchange发送消息-客户来源于官网-生产者--");

            //通过实体类对象实例构造消息-设置消息的持久化
            CustomerDto dto=new CustomerDto(20,"修罗 debug","官网");
            Message msg=MessageBuilder.withBody(new Gson().toJson(dto).getBytes())
                    .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
                    .build();
            //设置交换器，并将消息发送金交换器绑定的消息模型中
            rabbitTemplate.setExchange(env.getProperty("mq.topic.exchange.name"));
            //交换器需要设置为”途径“为官网的
            rabbitTemplate.setRoutingKey(env.getProperty("mq.topic.routing.key.cusotmer.gw"));
            rabbitTemplate.send(msg);

            log.info("基于TopicExchange消息模型发送消息 ~ 客户来源于官网 - 生产者成功发送消息...");
        }catch(Exception e){
            e.printStackTrace();
            status="failed";
        }
        return status;
    }

    //基于TopicExchange的消息模型发送消息 - 来源途径为微信号
    @RequestMapping(value = "send/topic/v2",method=RequestMethod.GET)
    public String sentTopicV2(){
        String status="success";
        try{
            log.info("\n\n --基于TopicExchange发送消息-客户来源于微信号-生产者--");

            //通过实体类对象实例构造消息-设置消息的持久化
            CustomerDto dto=new CustomerDto(21,"大圣 debug","微信公众号");
            Message msg=MessageBuilder.withBody(new Gson().toJson(dto).getBytes())
                    .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
                    .build();
            //设置交换器，并将消息发送金交换器绑定的消息模型中
            rabbitTemplate.setExchange(env.getProperty("mq.topic.exchange.name"));
            //交换器需要设置为”途径“为官网的
            rabbitTemplate.setRoutingKey(env.getProperty("mq.topic.routing.key.cusotmer.wx"));
            rabbitTemplate.send(msg);

            log.info("基于TopicExchange消息模型发送消息 ~ 客户来源于微信 - 生产者成功发送消息...");
        }catch(Exception e){
            e.printStackTrace();
            status="failed";
        }
        return status;
    }

    /**
     * 死信队列代码实战
     */
    @RequestMapping(value = "dead/queue/send",method = RequestMethod.GET)
    public String sendDeadQueueMsg(){
        String status="success";
        try{
            log.info("--死信队列消息模型实战之生产投递，发送消息---");
            //通过实体类对象实例构造消息--设置消息的持久化
            EventDto dto=new EventDto(21,"Customer","插入客户","插入客户信息");
            Message msg=MessageBuilder.withBody(new Gson().toJson(dto)
                    .getBytes())
                    .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
                    .build();
            //设置交换器，并将消息发送进交换器绑定的消息模型中
            rabbitTemplate.setExchange(env.getProperty("mq.dead.prod.exchange"));
            rabbitTemplate.setRoutingKey(env.getProperty("mq.dead.prod.routing.key"));
            rabbitTemplate.send(msg);
            log.info("基于死信队列消息模型实战之生产投递，发送消息--生产者成功发送消息...");
        }catch(Exception e){
            e.printStackTrace();
            status="failed";
        }
        return status;
    }

    /**
     * 延迟队列实战
     */
    @RequestMapping(value = "delay/queue/send",method = RequestMethod.GET)
    public String sendDelayQueueMsg(@RequestParam String userMsg,@RequestParam Long ttl){
        String status="success";
        try{
            //构造消息
            Message msg=MessageBuilder.withBody(userMsg.getBytes())
                    .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
                    .build();
            //发送消息进延迟交换器和路由键绑定的消息模型中
            rabbitTemplate.convertAndSend(env.getProperty("mq.delay.exchange"),
                    env.getProperty("mq.delay.routing.key"),
                    msg,
                    new MessagePostProcessor() {
                        @Override
                        public Message postProcessMessage(Message message) throws AmqpException {
                            //指定消息的存活时间ttl
                            MessageProperties mp=message.getMessageProperties();
                            mp.setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                            mp.setHeader("x-delay",ttl);

                            log.info("延迟队列生产者-发出消息：{}ttl:{}毫秒",userMsg,ttl);
                            return message;
                        }
                    });
        }catch(Exception e){
            status="failed";
        }
        return status;
    }




}
